﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace TestResizeCrop
{

    class Desk
    {
        public List<Lamp> Point_Max;
        public int[][] Matrix;
        public Desk(int[][] Matrix)
        {
            this.Matrix = Matrix;
            PrintMatrix(this.Matrix);
        }
        public void Scan()
        {
            Point_Max = FindMax();
            //FindAngle_start_end(Point_Max);
            Point_Max = FindMax();
        }
        private void FindAngle_start_end(List<Lamp> Point_Max)
        {
            int prevValue=0;
            int start=-1, end=-1;
            for (int i = 0; i < Point_Max.Count; i++)
            {
                start = -1; end = -1;
                prevValue = Point_Max[i].Value - Point_Max[i].kezev;
                if (Point_Max[i].x + 1 < Matrix.Length && Matrix[Point_Max[i].x + 1][Point_Max[i].y + 0] == prevValue)
                {   
                    start = (start==-1)? 0 :start;
                    end =0;
                }
                if (Point_Max[i].x + 1 < Matrix.Length && Point_Max[i].y - 1 > -1 && Matrix[Point_Max[i].x + 1][Point_Max[i].y - 1] == prevValue)
                {
                    start = (start == -1) ? 45 : start;
                    end = 45;
                }
                if (Point_Max[i].y - 1 > -1 && Matrix[Point_Max[i].x + 0][Point_Max[i].y - 1] == prevValue)
                {
                    start = (start == -1) ? 90 : start;
                    end = 90;
                }
                if (Point_Max[i].x - 1 > -1 && Point_Max[i].y - 1 > -1 && Matrix[Point_Max[i].x - 1][Point_Max[i].y - 1] == prevValue)
                {
                    start = (start == -1) ? 145 : start;
                    end = 145;
                }
                if (Point_Max[i].x - 1 > -1 && Matrix[Point_Max[i].x - 1][Point_Max[i].y + 0] == prevValue)
                {
                    start = (start == -1) ? 180 : start;
                    end = 180;
                }
                if (Point_Max[i].x - 1 > -1 &&       
                    Point_Max[i].y + 1 < Matrix[Point_Max[i].x - 1].Length && 
                    Matrix[Point_Max[i].x - 1][Point_Max[i].y + 1] == prevValue)
                {
                    start = (start == -1) ? 225 : start;
                    end = 225;
                }
                if (Point_Max[i].y + 1 < Matrix[Point_Max[i].x + 0].Length && 
                    Matrix[Point_Max[i].x + 0][Point_Max[i].y + 1] == prevValue)
                {
                    start = (start == -1) ? 270 : start;
                    end = 270;
                }
                if (Point_Max[i].x + 1 < Matrix.Length &&
                    Point_Max[i].y + 1 < Matrix[Point_Max[i].x + 1].Length && 
                    Matrix[Point_Max[i].x + 1][Point_Max[i].y + 1] == prevValue)
                {
                    start = (start == -1) ? 315 : start;
                    end = 315;
                }
                Point_Max[i].AngleStart = start;
                Point_Max[i].AngleEnd = end;

            }
        }

        public void toTextFile(string fileName)
        {
            TextWriter tw = new StreamWriter(fileName);
            foreach (Lamp lamp in this.Point_Max)
            {
             tw.WriteLine(lamp.x+" "+lamp.y+" "+ lamp.Value+" "+lamp.kezev);   
            }
            tw.Close();

        }

        private List<Lamp> FindMax()
        {
            List<Lamp> Max_P = new List<Lamp>();

            for (int i = 0; i < Matrix.Length; i++)
            {
                for (int j = 1; j < Matrix[i].Length; j++)
                {
                    Max_P.Add(new Lamp(i, j, Matrix[i][j], 0));
                }
            }

            Max_P = SortByNumbers(Max_P);
            RemoveAllZeroValu(Max_P);

            Lamp A, B;
            for (int i = 0; i < Max_P.Count; i++)
            {
                A = Max_P[i];
                for (int j = i; j < Max_P.Count - 1; j++)
                {
                    B = Max_P[j + 1];
                    if (
                    (Math.Abs(A.x - B.x) == 1 && Math.Abs(A.y - B.y) == 1) ||
                    (Math.Abs(A.x - B.x) == 0 && Math.Abs(A.y - B.y) == 1) ||
                    (Math.Abs(A.x - B.x) == 1 && Math.Abs(A.y - B.y) == 0)
                    )
                    {
                        if (A.Value <= B.Value)
                        {
                            B.kezev = B.Value - A.Value;
                            if (A.kezev != 0 && A.kezev != B.kezev)
                                Max_P.Remove(B);
                            else
                                Max_P.Remove(A);
                        }

                        i--;
                        break;
                    }
                }

            }
            RemoveAllZeroKetez(Max_P);

            return Max_P;
        }
        private void RemoveAllZeroValu(List<Lamp> Max_P)
        {
            for (int i = 0; i < Max_P.Count; i++)
                if (Max_P[i].Value == 0)
                    Max_P.Remove(Max_P[i--]);
        }
        private void RemoveAllZeroKetez(List<Lamp> Max_P)
        {
            for (int i = 0; i < Max_P.Count; i++)
                if (Max_P[i].kezev == 0)
                    Max_P.Remove(Max_P[i--]);
        }
        private List<Lamp> SortByNumbers(List<Lamp> Max_P)
        {
            List<Lamp> P = new List<Lamp>();
            int min;
            Lamp temp;
            for (int i = 0; i < Max_P.Count; )
            {
                min = Max_P[i].Value;
                temp = Max_P[0];
                for (int j = 1; j < Max_P.Count; j++)
                {
                    if (min > Max_P[j].Value)
                    {
                        min = Max_P[j].Value;
                        temp = Max_P[j];
                    }
                }
                P.Add(temp);
                Max_P.Remove(temp);
            }
            return P;
        }


        private void PrintMatrix(int[][] Mat)
        {
            System.Console.WriteLine("");
            System.Console.Write(" | 0 |");
            System.Console.Write(" 1 | ");
            System.Console.Write("2 | ");
            System.Console.Write("3 | ");
            System.Console.Write("4 | ");
            System.Console.Write("5 | ");
            System.Console.Write("6 | ");
            System.Console.WriteLine("7 | ");
            System.Console.WriteLine(" --------------------------------------");
            for (int x = 0; x < Mat.Length; x++)
            {
                System.Console.Write(" ||" + x + "|| ");

                for (int y = 0; y < Mat[x].Length; y++)
                {
                    System.Console.Write(Mat[x][y] + " | ");
                }
                System.Console.WriteLine("");
            }
        }
    }

    class Lamp
    {
        public int x, y;
        public int Value;
        public int kezev;
        public int AngleStart=-1; 
        public int AngleEnd=-1;

        public Lamp() { }
        public Lamp(int x, int y, int Value, int kezev)
        {
            this.x = x;
            this.y = y;
            this.Value = Value;
            this.kezev = kezev;

        }



    }
}
